package com.kamistoat.meimeistore.auth.controller;

import com.kamistoat.meimeistore.apisystem.feign.RemoteUserService;
import com.kamistoat.meimeistore.apisystem.model.LoginUser;
import com.kamistoat.meimeistore.auth.form.LoginBody;
import com.kamistoat.meimeistore.auth.form.RegisterBody;
import com.kamistoat.meimeistore.auth.service.SysLoginService;
import com.kamistoat.meimeistore.commoncore.constant.SecurityConstants;
import com.kamistoat.meimeistore.commoncore.domain.R;
import com.kamistoat.meimeistore.commoncore.utils.JwtUtils;
import com.kamistoat.meimeistore.commoncore.utils.StringUtils;
import com.kamistoat.meimeistore.commonredis.utils.RedissonUtils;
import com.kamistoat.meimeistore.commonsecurity.auth.AuthUtil;
import com.kamistoat.meimeistore.commonsecurity.utils.SecurityUtils;
import com.kamistoat.meimeistore.commonsecurity.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;

/**
 * 登录相关控制。还是在自己实现登录认证
 * 如果要移植到SpringSecurity需要大改这个controller。
 * 可以只将登录部分使用SSY，权限认证我觉得原项目的AOP就挺好的。
 */
@Controller
public class LoginController {
    @Autowired
    TokenUtils tokenUtils;
    @Autowired
    SysLoginService sysLoginService;
    @Autowired
    RemoteUserService remoteUserService;
    @Autowired
    AuthUtil authUtil;
    @Autowired
    RedissonUtils redissonUtils;

    @ResponseBody
    @GetMapping("test")
    public R<?> array() {
        ArrayList<Long> ik = new ArrayList<>();
        ik.add(1L);
        ik.add(3L);
        redissonUtils.setCacheObject("abcsg", ik);
        return R.ok();
    }

    /**
     * 登录
     */
    @ResponseBody
    @PostMapping("login")
    public R<?> login(@RequestBody LoginBody form) {
        // 用户登录
        LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
        // 若登录成功，则无异常，正确获取到 LoginUser。
        // 则将用户令牌进行缓存，同时根据用户令牌制作简易用户令牌，返回给前端。此后前端发来的请求都将携带简易用户令牌
        return R.ok(tokenUtils.createToken(userInfo));
    }

    /**
     * 登出
     */
    @ResponseBody
    @GetMapping("logout")
    public R<?> logout() {
        // 从当前请求中提取出简易用户令牌
        String jwtToken = SecurityUtils.getJwtToken();
        if (StringUtils.isNotEmpty(jwtToken)) {
            String username = JwtUtils.getUserName(jwtToken);
            // 记录用户退出日志
            sysLoginService.recordLogoutInfor(username);
            // 删除缓存中的用户令牌
            authUtil.logout(jwtToken);
        }
        return R.ok();
    }

    /**
     * 刷新缓存中用户令牌的有效期
     */
    @ResponseBody
    @PostMapping("refresh")
    public R<?> refresh() {
        // 根据当前请求的简易令牌, 获取缓存中的 后端登录令牌
        LoginUser loginLoginUser = tokenUtils.getLoginLoginUser();

        // 核心信息令牌直接从数据库中重新获取，并非从缓存中提取
        R<LoginUser> coreLoginUserR = remoteUserService.getUserInfoByUserId(SecurityUtils.getUserId(), SecurityConstants.INNER);

        // 刷新 后端登录令牌 有效期
        if (StringUtils.isNotNull(loginLoginUser)) {
            tokenUtils.refreshToken(loginLoginUser);
        }

        // 刷新 核心信息令牌 有效期
        if(coreLoginUserR.getCode() == R.SUCCESS){
            tokenUtils.refreshCoreLoginUser(coreLoginUserR.getData());
        }

        return R.ok();
    }

    /**
     * 注册
     */
    @ResponseBody
    @PostMapping("register")
    public R<?> register(@RequestBody RegisterBody registerBody) {
        // 用户注册
        sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
        return R.ok();
    }
}
